package com.bsj.sipgateway.web.controller;

import com.bsj.power.common.annotation.Log;
import com.bsj.power.common.config.exception.ApiException;
import com.bsj.power.common.config.global.JsonResult;
import com.bsj.power.common.config.global.JsonResultEnum;
import com.bsj.power.common.constant.SysLogTitleConst;
import com.bsj.power.common.def.entity.gb28181.Device;
import com.bsj.power.common.def.entity.gb28181.DeviceChannel;
import com.bsj.power.common.def.enums.BusinessType;
import com.bsj.power.common.mapper.DeviceChannelMapper;
import com.bsj.power.common.util.DateUtils;
import com.bsj.power.common.util.StringUtils;
import com.bsj.sipgateway.common.def.RecordFile;
import com.bsj.sipgateway.common.def.RecordList;
import com.bsj.sipgateway.sip.transmit.cmd.impl.SIPCommander;
import com.bsj.sipgateway.util.RecordInfoUtil;
import com.bsj.sipgateway.web.service.IDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.bsj.JedisClusterBSJ;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 实时直播与回放
 * @menu 实时直播
 * @Author zhaoyang
 * @Date 2024/4/24 10:01
 */
@RestController
@RequestMapping(value = "/api/stream")
@Slf4j
//@SaCheckPermission("/video/api/stream")
public class ApiStreamController {


    @Autowired
    private SIPCommander sipCommander;

    @Autowired
    private JedisClusterBSJ jedisClusterBSJ;

    @Autowired
    @Qualifier("deviceServiceImpl")
    private IDeviceService deviceService;

    @Autowired
    private DeviceChannelMapper deviceChannelMapper;

    /**
     * @param deviceId      设备国标id
     * @param channelSerial 逻辑通道号，默认是1，取第一通道，一个设备至少有一个通道
     * @param bitStream     分辨率/码流：主码流：6-1080P 子码流：5-720P
     * @return: com.bsj.power.common.config.global.JsonResult
     * @decription
     */
    @Deprecated // 项目初始阶段调试使用，可废弃
    @RequestMapping("/start")
    public JsonResult start(@RequestParam String deviceId, @RequestParam(required = false) Integer channelSerial, @RequestParam Integer bitStream) {
        if (channelSerial == null) {
            channelSerial = 1;
        }
        sipCommander.playStreamCmd(deviceId, channelSerial, bitStream);
        return JsonResult.success();
    }


    /**
     * 直播流停止
     *
     * @param deviceId      设备国标id
     * @param type          关闭的类型，实时视频0 历史回放视频1
     * @param channelSerial 逻辑通道号
     * @return: com.alibaba.fastjson.JSONObject
     * @decription 直播流停止
     */
    @RequestMapping("/stop")
    public JsonResult stop(@RequestParam String deviceId, @RequestParam String type, @RequestParam(required = false) Integer channelSerial) {
        if (channelSerial == null) {
            // 默认取设备的第一个通道
            channelSerial = 1;
        }
        sipCommander.streamByeCmd(deviceId, type, channelSerial);
        return JsonResult.success();
    }


    /**
     * 手动重置直播通道状态
     *
     * @param deviceId
     * @return
     */
    @RequestMapping("/updatePlayStreamState")
    public JsonResult updatePlayStreamState(@RequestParam String deviceId) {
        if (StringUtils.isEmpty(deviceId)) {
            return JsonResult.fail(JsonResultEnum.PARAM_ERROR);
        }
        String type = "0";
        Integer channelSerial = 0;
        sipCommander.updatePlayStreamState(deviceId, type, channelSerial);
        return JsonResult.success();
    }


    /**
     * 查询设备回放列表，下发查询命令
     *
     * @param deviceId
     * @param channelSerial
     * @param startTime     yyyy-MM-dd HH:mm:ss
     * @param endTime       yyyy-MM-dd HH:mm:ss
     * @return
     */
    @RequestMapping("/recordInfoQuery")
    public JsonResult recordInfoQuery(String deviceId, Integer channelSerial, String startTime, String endTime) {
        if (deviceId == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        Device dbDevice = deviceService.selectByDeviceId(deviceId);
        if (dbDevice == null) {
            throw new ApiException(JsonResultEnum.DEVICE_NOT_EXIST);
        }
        if (channelSerial == null) {
            channelSerial = 1;
        }
        boolean flag = sipCommander.recordInfoQuery(deviceId, channelSerial, startTime, endTime);
        JsonResult jsonResult;
        if (flag) {
            jsonResult = JsonResult.success();
            jsonResult.setData(dbDevice.getId());
        } else {
            jsonResult = JsonResult.fail();
        }
        return jsonResult;
    }

    /**
     * 定时轮询回放录像文件
     *
     * @param did
     * @param startTime yyyy-MM-dd HH:mm:ss
     * @param endTime
     * @return
     */
    @RequestMapping("/getRecordInfo")
    public JsonResult getRecordInfo(@RequestParam Long did, @RequestParam String startTime
            , @RequestParam String endTime, Integer channelSerial, String channelId) {
        if (did == null || startTime == null || endTime == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        if (channelSerial == null) {
            channelSerial = 1;
        }
        Integer finalChannelSerial = channelSerial;
        if (channelId == null) {
            Device device = deviceService.selectById(did);
            String deviceId = device.getDeviceId();
            DeviceChannel deviceChannel = deviceChannelMapper.queryChannelByDeviceIdAndSerial(deviceId, channelSerial);
            channelId = deviceChannel.getChannelId();
        }

        RecordList recordList = RecordInfoUtil.findRecordInfo(channelId, startTime, endTime, jedisClusterBSJ);
        if (recordList == null) {
            JsonResult jsonResult = new JsonResult();
            jsonResult.setCode(-1);
            jsonResult.setMsg("没有查询到回放列表");
            return jsonResult;
        }
        long startLong = DateUtils.strToDate(DateUtils.TIME_STANDARD_FORMAT, startTime).getTime();
        long endLong = DateUtils.strToDate(DateUtils.TIME_STANDARD_FORMAT, endTime).getTime();

        Device device = deviceService.selectById(did);

        List<RecordFile> listFile = recordList.getListFile();
        // 按照开始时间排序
        List<RecordFile> sorted = listFile.stream().filter(recordFile -> recordFile.getChannel() == finalChannelSerial)
                .sorted(Comparator.comparing(RecordFile::getBegintime)).collect(Collectors.toList());
        // 判断第一条的开始时间如果大于当天的时间，就把它改为当天的0点01分
        if (sorted.get(0).getBegintime() < startLong) {
            sorted.get(0).setBegintime(startLong + 60000);
        }

        List<RecordFile> filterList = sorted;
        filterList.stream().forEach(recordFile -> {
            if (StringUtils.isEmpty(recordFile.getDevice())) {
                recordFile.setDevice(device.getId() + "");
            }
            recordFile.setDeviceId(device.getDeviceId());
            recordFile.setNickName(device.getNickName());
            long begintime = recordFile.getBegintime();
            long endtime = recordFile.getEndtime();
            recordFile.setBegintime(begintime / 1000);
            recordFile.setEndtime(endtime / 1000);
        });
        JsonResult jsonResult = JsonResult.success();
        jsonResult.setTotal(filterList.size());
        jsonResult.setData(filterList);
        return jsonResult;
    }

    /**
     * 开始回放
     *
     * @param startTime     yyyy-MM-dd HH:mm:ss
     * @param endTime       yyyy-MM-dd HH:mm:ss
     * @param deviceId      设备国标id
     * @param channelSerial 设备逻辑通道号
     * @return
     */
    @RequestMapping("playBackStart")
    public JsonResult playBackStart(@RequestParam Long startTime, @RequestParam Long endTime, @RequestParam String deviceId, @RequestParam(required = false) Integer channelSerial) {
        if (channelSerial == null) {
            channelSerial = 1;
        }
//        sipCommander.playbackStreamCmd(startTime, endTime, deviceId, channelSerial);
        return JsonResult.success();
    }


    /**
     * 手动打开直播操作的记录
     *
     * @param deviceId      设备国标id
     * @param channelSerial 设备逻辑通道号
     * @param bitStream     码流类型
     * @return
     */
    @GetMapping("/playOperatorRecord")
    @Log(title = SysLogTitleConst.VIDEO_VIEWING, desc = "打开直播：", businessType = BusinessType.VIDEO_VIEWING)
    public JsonResult playOperatorRecord(String nickName, String deviceId, Integer channelSerial, Integer bitStream) {
        return JsonResult.success();
    }


    /**
     * 手动打开回放操作的记录
     *
     * @param startTime     yyyy-MM-dd HH:mm:ss
     * @param endTime       yyyy-MM-dd HH:mm:ss
     * @param deviceId      设备国标id
     * @param channelSerial 设备逻辑通道号
     * @return
     */
    @GetMapping("/playBackOperatorRecord")
    @Log(title = SysLogTitleConst.VIDEO_VIEWING, desc = "打开回放：", businessType = BusinessType.VIDEO_VIEWING)
    public JsonResult playBackOperatorRecord(String nickName, Long startTime, Long endTime, String deviceId, Integer channelSerial) {
        return JsonResult.success();
    }

    /**
     * 回放下载的操作记录
     *
     * @param startTime
     * @param endTime
     * @param deviceId
     * @param channelSerial
     * @return
     */
    @GetMapping("/playBackDownloadRecord")
    @Log(title = SysLogTitleConst.PLAY_BACK_DOWNLOAD, desc = "回放下载：", businessType = BusinessType.PLAY_BACK_DOWNLOAD)
    public JsonResult playBackDownloadRecord(String nickName, String startTime, String endTime, String deviceId, Integer channelSerial) {
        return JsonResult.success();
    }

    /**
     * 云台控制的操作记录
     *
     * @param deviceId
     * @param command
     * @param moveSpeed
     * @param channelSerial
     * @return
     */
    @GetMapping("/ptzControlRecord")
    @Log(title = SysLogTitleConst.PTZ_CONTROL, desc = "云台控制：", businessType = BusinessType.PTZ_CONTROL)
    public JsonResult ptzControlRecord(String nickName, String deviceId, String command, Integer moveSpeed, Integer channelSerial) {
        return JsonResult.success();
    }


//    @GetMapping("/videoDeviceAlarmRecord")
//    @Log(title = SysLogTitleConst.VIDEO_VIEWING, desc = "异常通知：", businessType = BusinessType.ALARM_EXCEPTION_NOTIFY)
//    public JsonResult videoDeviceAlarmRecord(String nickName) {
//        return JsonResult.success();
//    }


}
